﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Effects.Wave;
using Effects.Effects;


/********************** ************************
 * WORK FILE FOR TESTING, NO SERIOUS CODE, YET *
 ***********************************************/

namespace Effects.Testing
{
    /*
    class Program
    {
        private static int frameSize = 128;

        // creates array of Effect acording to given args
        private static Effect[] CreateEffects(string[] effectArgs, uint sampleRate,int dataSize,int overlap)
        {
            try
            {
                List<Effect> effects = new List<Effect>();
                int i = 0;
                while (i < effectArgs.Length)
                {
                    switch (effectArgs[i])
                    {
                        case "-tremolo":
                            // create tremolo
                            Tremolo trem = new Tremolo();
                            i++;
                            // set parameters
                            int speed = Int32.Parse(effectArgs[i]);
                            trem.Speed = speed;
                            i++;
                            double depth = double.Parse(effectArgs[i]);
                            trem.Depth = depth;
                            SetCommonProperties(trem, sampleRate, overlap, dataSize);
                            effects.Add(trem);
                            i++;
                            break;

                        case "-flanger":
                            Flanger flange = new Flanger();
                            // expects speed and depth params
                            i++;
                            speed = Int32.Parse(effectArgs[i]);
                            flange.Speed = speed;
                            i++;
                            depth = double.Parse(effectArgs[i]);
                            flange.Depth = depth;
                            SetCommonProperties(flange, sampleRate, overlap, dataSize);
                            effects.Add(flange);
                            i++;
                            break;

                        case "-delay":
                            Delay delay = new Delay();
                            i++;
                            // params for delayTime  and depth expected
                            int delayTime = Int32.Parse(effectArgs[i]);
                            delay.DelayTime = delayTime;
                            i++;
                            depth = double.Parse(effectArgs[i]);
                            delay.Depth = depth;
                            SetCommonProperties(delay, sampleRate, overlap, dataSize);
                            effects.Add(delay);
                            i++;
                            break;

                        case "-multidelay":
                            MultiDelay mdelay = new MultiDelay();
                            i++;
                            delayTime = Int32.Parse(effectArgs[i]);
                            mdelay.DelayTime = delayTime;
                            i++;
                            depth = double.Parse(effectArgs[i]);
                            mdelay.Depth = depth;
                            i++;
                            int repeats = Int32.Parse(effectArgs[i]);
                            mdelay.Repeats = repeats;
                            SetCommonProperties(mdelay, sampleRate, overlap, dataSize);
                            effects.Add(mdelay);
                            i++;
                            break;

                        case "-pitchshift":
                            PitchShifter pshift = new PitchShifter();
                            i++;
                            double shift=double.Parse(effectArgs[i]);
                            pshift.PitchShift = shift;
                            i++;
                            int overFactor=Int32.Parse(effectArgs[i]);
                            if (overFactor < 1 || overFactor > 32 || overFactor!=FFT.nexPowerOf2(overFactor))
                                throw new ArgumentException("Nespravny tvar parametrov");
                            SetCommonProperties(pshift, sampleRate, overFactor, dataSize);
                            effects.Add(pshift);
                            i++;
                            break;

                        default:
                            throw new ArgumentException("Uknown parameter: " + effectArgs[i]);
                    }
                }

                return effects.ToArray();
            }
            catch (ArgumentException e)
            {
                throw new Exception(e.Message);
            }
        }

        // sets common parameters to the given effects - sample rate, overlap factor and frame size (number of samples in 1 frame)
        static void SetCommonProperties(Effect effects, uint sampleRate, int overlap, int dataSize)
        {
                effects.DataSize = dataSize;
                effects.SampleRate = sampleRate;
                effects.Overlap = overlap;
        }


        static void Effect(string inFile, string outFile, string[] effectArgs)
        {
            try
            {
                
                
                // load file
                Wave.WaveReader input = new WaveReader(inFile);
                Wave.Wave data = input.Load();

                // create effects
                Effect[] fxs = CreateEffects(effectArgs,data.FmtChunk.SampleRate,frameSize,1);

                // create output Wave.wave
                Wave.Wave dataOut = new Wave.Wave(new DataChunk(0), data.FmtChunk, 0);

                // processing
                Process(data, dataOut, fxs);

                // write new file
                WaveWriter writer = new WaveWriter(outFile);
                writer.Wave = dataOut;
                writer.Write();
            }
            catch (NullReferenceException e)
            {
                Console.WriteLine("An error accured while attempting to read file: " + inFile);
            }
            catch (FormatException e)
            {
                Console.WriteLine("Some arguments have wrong format");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }

        // Processing input data
        
        private static void Process(Wave.Wave input, Wave.Wave output,Effect[] effects)
        {
            int frameSize=128;
            double[] buffer = new double[frameSize];
            int counter = 0;
            /*
            foreach (double sample in input.GetSampleDoubleEnumerator)
            {
                buffer[counter] = sample;
                counter++;

                if (counter == frameSize)
                {
                    double[] processBuffer = buffer;
                    for (int i = 0; i < effects.Length; i++)
                    {
                        processBuffer = effects[i].Effect(processBuffer);
                    }

                    output.ToAppend(processBuffer);
                    buffer = new double[frameSize];
                    counter = 0;
                }
            }

            // now process reamining samples -  adding zeros, and processing
            while (counter < frameSize)
            {
                buffer[counter] = 0;
                counter++;
            }

            for (int i = 0; i < effects.Length; i++)
            {
                buffer = effects[i].Effect(buffer);
            }
            output.ToAppend(buffer);
            
            //append data
            output.Append();
        } 

        // method prints help
/*
        static void PrintHelp()
        {
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Parameter syntax: <input file> <output file> <effect parameters>");
            Console.WriteLine("Where effect parameters are: <key word for effect> <params for effect>");
            Console.WriteLine();
            Console.WriteLine("Effect list:");
            Console.WriteLine("Flanger: -flanger <Speed in miliseconds> <Depth 0-0.5>");
            Console.WriteLine("Delay: -delay <DelayTime in miliseconds> <Depth 0-0.5>");
            Console.WriteLine("MultiDelay: -multidelay <DelayTime in miliseconds> <Depth 0-0.5> <Repeats>");
            Console.WriteLine("Tremolo: -tremolo <Speed in miliseconds> <Depth 0.0-1.0>");
            Console.WriteLine("Pitch Shifter: -pitchshift <Shift factor 0.5 - 2.0> <Overlap Factor - power of 2 between 1 and 32>");
            Console.WriteLine();

        }

        static void Main(string[] args)
        {
            //System.IO.BinaryWriter wrt=new System.IO.BinaryWriter(new System.IO.FileStream("bla", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write),Encoding.Unicode);
            
            //System.Windows.Forms.Application.Run(new BlaForm());
            //System.Windows.Forms.Application.Run(new Form1());
            Wave.Wave wav = new Wave.WaveReader("magnificient_seven.wav").Load();
            WaveWriter write = new WaveWriter("seremkocky");
            write.Wave = wav;
            write.Write();

            /*BlaForm bla=new BlaForm();
            global::Effects.GUI.EffectBoard board = new global::Effects.GUI.EffectBoard();
            board.Add(new Effects.GUIEffects.Delay());

            //EffectStreamPlayer play = new EffectStreamPlayer(bla, wav, new global::Effects.GUI.EffectBoard());
            EffectStreamPlayer play = new EffectStreamPlayer(bla, wav, board);
            System.Threading.Thread.Sleep(1000);
            play.Play();
            System.Windows.Forms.Application.Run(bla);
            */

            /*System.Media.SoundPlayer player = new System.Media.SoundPlayer("pok3.wav");
            player.Load();
            Console.WriteLine("File loaded");
            player.PlayLooping();
            System.Threading.Thread.Sleep(500);
            player.Stop();
            Console.WriteLine("Stopped");
            Console.ReadLine();
            player.Play();*/


            /*FFT f=new FFT(32);
            double[] pole = new double[32];
            pole[0] = 1;
            for(int i=1;i<32;i++)
                pole[i]=((double) 1)/i;

            f.Fft(ref pole);
            for (int i = 0; i < 32; i++)
                Console.WriteLine(pole[i]);

            Console.ReadLine();
             */
            
            /*
            if (args.Length == 0)
            {
                Console.WriteLine("Try -h parameter for help");
            }
            else if (args[0] == "-h")
            {
                PrintHelp();
            }
            else
            {
                try
                {
                    string inFile = args[0];
                    string outFile = args[1];
                    string[] fxArgs = new string[args.Length - 2];
                    Array.Copy(args, 2, fxArgs, 0, args.Length - 2);

                    Effect(inFile, outFile, fxArgs);
                    Console.WriteLine("Finished");
                }
                catch (Exception e)
                {
                    Console.WriteLine("An error ocured: " + e.Message);
                }
            }
            //Console.ReadLine();
             * */ /*
        }
    } */
    public class Program
    {
        static void Main(string[] args)
        { }
    }
}
